import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'api_exception.dart';
import '../model/base_response.dart';
import 'http_agent.dart';
import 'request_api.dart';
import 'signature_utils.dart';

///超时时间
const Duration connnectTimeout = Duration(seconds: 30);

///接收超时时间
const Duration receiveTimeout = Duration(seconds: 30);

///发送超时时间
const Duration sendTimeout = Duration(seconds: 30);

class HttpRequest {
  static Dio? _dio;

  static Dio createInstance([bool isJson = true]) {
    print( "生成了请求token=== ${HttpAgent().token}");
    _dio = Dio(BaseOptions(
        baseUrl: RequestApi.BASE_URL,
        connectTimeout: connnectTimeout,
        receiveTimeout: receiveTimeout,
        sendTimeout: sendTimeout,
        contentType: Headers.multipartFormDataContentType,
        headers: {
          "Request-User-Agent": HttpAgent().userAgent(),
          "language": "zh",
          "Authorization": HttpAgent().token
        },
        validateStatus: (status) {
          return true;
        }));
    return _dio!;
  }

  /// 获取公共参数
  static Map<String, dynamic> _getCommonParams() {
    final httpAgent = HttpAgent();
    print("uid: ${httpAgent.uid}");
    print("device: ${httpAgent.androidid}");
    final params = <String, dynamic>{
      'uid': httpAgent.uid ?? "0",
      'version': httpAgent.version,
      'language': httpAgent.language,
      'device': httpAgent.device,
      'androidid': httpAgent.androidid,
      'timestamp': httpAgent.timestamp,
      // 'xtest': "1024CxNqmt0LTa4IckJ",
    };

    // 只有当uid不为空时才添加
    final uid = httpAgent.uid;
    if (uid != null && uid.isNotEmpty) {
      params['uid'] = uid;
    }
    return params;
  }

  /// 清理参数，移除 null 值
  static Map<String, dynamic> _cleanParams(Map<String, dynamic>? params) {
    if (params == null) return {};

    final cleanedParams = <String, dynamic>{};
    params.forEach((key, value) {
      // 只保留非空且非 null 的值
      if (value != null &&
          value.toString().isNotEmpty &&
          value.toString().toLowerCase() != 'null') {
        cleanedParams[key] = value;
      }
    });

    return cleanedParams;
  }

  /// 合并公共参数并添加签名（修复：只对业务参数签名）
  static Map<String, dynamic> _mergeCommonParamsWithSignature(
      Map<String, dynamic>? data) {
    final cleanedData = _cleanParams(data);
    final commonParams = _getCommonParams();

    final allParams = {...commonParams, ...cleanedData};

    SignService signService = SignService();
    Map<String, dynamic> tempParams = Map.from(allParams);
    signService.deepKsort(tempParams); // 需要将_deepKsort改为公共方法
    final signStr = signService.deepNewString(tempParams);
    final signature =
        signService.signWithSHA1RSA(signStr, SignService.newPrivateKey);

    final finalParams = {...allParams, 'sign': signature};

    return finalParams;
  }

  ///统一请求方法
  static Future<BaseResponse<T>> request<T>(Method method, String path,
      {Map<String, dynamic>? params,
      dynamic data,
      String? baseurl,
      bool isJson = true,
      bool showLoading = false,
      T Function(dynamic)? fromJsonT}) async {
    try {
      if (showLoading) {
        // 显示加载框
        // TODO: 实现加载框显示逻辑
      }

      ///1.检测网络链接状态
      // TODO: 添加网络状态检测

      /// 2.请求
      Dio dio = createInstance(isJson);

      if (baseurl != null) {
        dio.options.baseUrl = baseurl;
      }

      Map<String, dynamic>? requestData = data;
      if (method == Method.POST) {
        requestData = _mergeCommonParamsWithSignature(data);
      }

      Response resp = await dio.request(path,
          options: Options(
            method: _methonValue[method],
          ),
          data: FormData.fromMap(requestData ?? {}),
          queryParameters: params);

      // 统一处理响应
      print("HttpRequest response: ${resp}");
      return _handleResponse<T>(resp, fromJsonT);
    } on DioException catch (e) {
      // 统一处理Dio异常
      throw _handleDioException(e);
    } catch (e) {
      // 处理其他异常
      throw ApiException(
        code: ApiException.UNKNOWN_ERROR,
        message: ApiException.getErrorMessage(ApiException.UNKNOWN_ERROR),
        details: e.toString(),
      );
    } finally {
      if (showLoading) {
        // 隐藏加载框
        // TODO: 实现加载框隐藏逻辑
      }
    }
  }

  /// 统一处理响应数据（修复：改进解析逻辑）
  static BaseResponse<T> _handleResponse<T>(
      Response response, T Function(dynamic)? fromJsonT) {
    // print("HttpRequest response: ${response.data}");

    // 检查HTTP状态码
    if (response.statusCode == null ||
        response.statusCode! < 200 ||
        response.statusCode! >= 300) {
      throw ApiException(
        code: response.statusCode ?? ApiException.SERVER_ERROR,
        message: _getHttpErrorMessage(response.statusCode),
        details: response.statusMessage,
      );
    }

    // 检查响应数据
    if (response.data == null) {
      throw ApiException(
        code: ApiException.PARSE_ERROR,
        message: ApiException.getErrorMessage(ApiException.PARSE_ERROR),
      );
    }

    try {
      // 解析响应数据
      if (response.data is Map<String, dynamic>) {
        final responseData = response.data as Map<String, dynamic>;

        // 创建BaseResponse对象
        final baseResponse = BaseResponse<T>.fromJson(responseData, fromJsonT);

        // 检查业务逻辑错误
        if (!baseResponse.isSuccess) {
          throw ApiException(
            code: baseResponse.code,
            message: baseResponse.message,
            details: 'API返回错误码: ${baseResponse.code}',
          );
        }

        return baseResponse;
      } else if (response.data is String) {
        // 处理字符串响应（可能是JSON字符串）
        try {
          final jsonData = jsonDecode(response.data);
          if (jsonData is Map<String, dynamic>) {
            return BaseResponse<T>.fromJson(jsonData, fromJsonT);
          }
        } catch (e) {
          // 如果不是JSON，直接返回字符串数据
        }

        return BaseResponse<T>(
          code: 200,
          message: 'success',
          data: response.data,
          success: true,
        );
      } else {
        // 其他类型的响应数据
        return BaseResponse<T>(
          code: 200,
          message: 'success',
          data: response.data,
          success: true,
        );
      }
    } catch (e) {
      // print('响应解析错误: $e');
      throw ApiException(
        code: ApiException.PARSE_ERROR,
        message: ApiException.getErrorMessage(ApiException.PARSE_ERROR),
        details: e.toString(),
      );
    }
  }

  /// 处理Dio异常
  static ApiException _handleDioException(DioException e) {
    // print('Dio异常: ${e.type}, 消息: ${e.message}');

    switch (e.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
        return ApiException(
          code: ApiException.TIMEOUT_ERROR,
          message: ApiException.getErrorMessage(ApiException.TIMEOUT_ERROR),
          details: e.message,
        );
      case DioExceptionType.connectionError:
        return ApiException(
          code: ApiException.NETWORK_ERROR,
          message: ApiException.getErrorMessage(ApiException.NETWORK_ERROR),
          details: e.message,
        );
      case DioExceptionType.badResponse:
        return ApiException(
          code: e.response?.statusCode ?? ApiException.SERVER_ERROR,
          message: _getHttpErrorMessage(e.response?.statusCode),
          details: e.message,
        );
      default:
        return ApiException(
          code: ApiException.UNKNOWN_ERROR,
          message: e.message ??
              ApiException.getErrorMessage(ApiException.UNKNOWN_ERROR),
        );
    }
  }

  /// 获取HTTP错误信息
  static String _getHttpErrorMessage(int? statusCode) {
    if (statusCode == null) return '网络请求失败';

    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权访问';
      case 403:
        return '禁止访问';
      case 404:
        return '请求的资源不存在';
      case 500:
        return '服务器内部错误';
      case 502:
        return '网关错误';
      case 503:
        return '服务不可用';
      default:
        if (statusCode >= 500) {
          return '服务器错误($statusCode)';
        } else if (statusCode >= 400) {
          return '客户端错误($statusCode)';
        } else {
          return '请求失败($statusCode)';
        }
    }
  }
}

///请求类型
enum Method {
  GET,
  POST,
}

///请求类型值
const _methonValue = {
  Method.GET: "GET",
  Method.POST: "POST",
};
